using System;
using System.Collections.Generic;
using KaytechSoftware.Cms.App.Common;
using KaytechSoftware.Cms.Common.Extensions;

namespace KaytechSoftware.Cms.App.Areas.Admin.Models.Base
{
    public class GridModel
    {
        public IList<GridColumnDescriptor> Columns { get; private set; }
        public IList<GridRow> Rows { get; private set; }
        public GridFiltersModel Filters { get; set; }

        public GridModel(IList<GridEntityModel> items)
        {
            Columns = new List<GridColumnDescriptor>();
            Rows = new List<GridRow>();

            FillColumns(items);
            FillRows(items);
        }

        public GridModel(IList<GridEntityModel> items, GridFiltersModel filterses) : this(items)
        {
            Filters = filterses;
        }

        private void FillColumns(IList<GridEntityModel> items)
        {
            if (items.Count == 0)
                return;

            var properties = items[0].GetType().GetProperties();
            foreach (var propertyInfo in properties)
            {
                var skip = propertyInfo.GetCustomAttributes(typeof(SkipInGridAttribute), true);
                if (skip.Length > 0)
                    continue;

                var labels = propertyInfo.GetCustomAttributes(typeof(LabelAttribute), true);
                if (labels.Length == 0)
                    continue;

                var label = (LabelAttribute) labels[0];
                Columns.Add(new GridColumnDescriptor {NameResourceKey = label.ResourceKey});
            }
        }

        private void FillRows(IList<GridEntityModel> items)
        {
            foreach (var item in items)
            {
                var row = new GridRow();
                foreach (var propertyInfo in item.GetType().GetProperties())
                {
                    var skip = propertyInfo.GetCustomAttributes(typeof(SkipInGridAttribute), true);
                    if (skip.Length > 0)
                        continue;

                    var ids = propertyInfo.GetCustomAttributes(typeof(IdAttribute), true);
                    if (ids.Length > 0)
                        row.Id = (long)propertyInfo.GetValue(item);

                    var renderers = propertyInfo.GetCustomAttributes(typeof(RendererAttribute), true);
                    if (renderers.Length == 0)
                        continue;

                    var cell = new GridCell();
                    cell.Text = propertyInfo.GetValue(item).ToStringSafely();

                    var actionLinks = propertyInfo.GetCustomAttributes(typeof(ActionLinkAttribute), true);
                    if (actionLinks.Length > 0)
                    {
                        cell.Action = ((ActionLinkAttribute) actionLinks[0]).Action;
                        cell.IsActionLink = true;
                    }

                    var renderer = (RendererAttribute)renderers[0];
                    switch (renderer.Type)
                    {
                        case RendererType.TextBox: case RendererType.DropDown:
                            cell.TextAlign = GridTextAlign.Left;
                        break;
                        case RendererType.TextArea:
                            cell.TextAlign = GridTextAlign.Justify;
                        break;
                        case RendererType.Integer: case RendererType.Decimal:
                            cell.TextAlign = GridTextAlign.Right;
                        break;
                        case RendererType.Image:
                            cell.Image = propertyInfo.GetValue(item) as PhotoDescriptor;
                            cell.IsImageCell = true;
                            var links = propertyInfo.GetCustomAttributes(typeof (LinkAttribute), true);
                            if (links.Length > 0 && ((LinkAttribute) links[0]).Type == LinkType.Edit)
                                cell.IsEditLink = true;
                        break;
                    }

                    row.Cells.Add(cell);
                }

                Rows.Add(row);
            }
        }

        public string ControllerName { get; set; }
    }
}